﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;
using System.Xml;
using System.Collections;

namespace Cn.Edwon.Web.Validation {
    public class NhbmMethod {

        public static String Message = "";

        /// <summary>
        /// 使用默认Mapping的命名规则和存放位置：$Assembly.Data.Mapping.$EOName.hbm.xml
        /// </summary>
        /// <typeparam name="T">EO的type</typeparam>
        /// <param name="propertyName">属性名</param>
        /// <returns>返回对EO内所有Property的解析（不包括主键）</returns>
        public static IDictionary<String,EONhbmCase> Parse<T>() {
            Type eoType = typeof(T);
            return Parse(eoType);
        }
        public static IDictionary<String, EONhbmCase> Parse(Type eoType) {
            String eoName = eoType.Name;
            Assembly assem = eoType.Assembly;
            String assemName = assem.GetName().Name;
            String resource = assemName + ".Data.Mapping." + eoName + ".hbm.xml";
            return ParseByAssembly(assem, resource);
        }
        /// <summary>
        /// 使用默认Mapping的命名规则和存放位置：$Assembly.Data.Mapping.$EOName.hbm.xml
        /// </summary>
        /// <typeparam name="T">EO的type</typeparam>
        /// <param name="propertyName">属性名</param>
        /// <returns></returns>
        public static EONhbmCase Parse<T>(String propertyName) {
            Type eoType = typeof(T);
            return Parse(eoType, propertyName);
        }
        public static EONhbmCase Parse(Type eoType,String propertyName) {
            String eoName = eoType.Name;
            Assembly assem = eoType.Assembly;
            String assemName = assem.GetName().Name;
            String resource = assemName + ".Data.Mapping." + eoName + ".hbm.xml";
            return ParseByAssembly(assem, resource, propertyName);
        }
        public static EONhbmCase ParseByAssembly(Assembly assem,String assemblyResource, String propertyName) {
            Stream xmlStream = assem.GetManifestResourceStream(assemblyResource);
            return Parse(xmlStream, propertyName);
        }
        public static IDictionary<String, EONhbmCase> ParseByAssembly(Assembly assem, String assemblyResource) {
            Stream xmlStream = assem.GetManifestResourceStream(assemblyResource);
            return Parse(xmlStream);
        }
        public static IDictionary<String, EONhbmCase> Parse(Stream xmlStream) {
            XmlDocument doc = new XmlDocument();
            XmlNamespaceManager xnm = new XmlNamespaceManager(new NameTable());
            xnm.AddNamespace("nh", "urn:nhibernate-mapping-2.2");
            doc.Load(xmlStream);
            XmlNodeList nodes = doc.SelectNodes("//nh:class/nh:property", xnm);
            IDictionary<String, EONhbmCase> dict = new Dictionary<String, EONhbmCase>();
            foreach (XmlNode node in nodes) {
                dict.Add(node.Attributes["name"].Value,Parse(node));
            }
            return dict;
        }
        public static EONhbmCase Parse(Stream xmlStream, String propertyName) {
            XmlDocument doc = new XmlDocument();
            XmlNamespaceManager xnm = new XmlNamespaceManager(new NameTable());
            xnm.AddNamespace("nh", "urn:nhibernate-mapping-2.2");
            doc.Load(xmlStream);
            XmlNode node = doc.SelectSingleNode("//nh:class/nh:property[@name='" + propertyName + "']", xnm);
            return Parse(node);
        }
        public static EONhbmCase Parse(XmlNode node) {
            if (node == null) return null;
            EONhbmCase enc = new EONhbmCase();
            enc.PropertyName = node.Attributes["name"].Value;
            try {
                enc.NotNull = (node.Attributes["not-null"].Value == "true");
            } catch {
                enc.NotNull = false;
            }
            try {
                enc.Type = Type.GetType(node.Attributes["type"].Value);
                if (enc.Type == null) enc.Type = typeof(String);
            } catch {
                enc.Type = typeof(String);
            }
            try {
                enc.Length = Convert.ToInt32(node.Attributes["length"].Value);
            } catch {
                enc.Length = -1;
            }
            return enc;
        }

        public static Boolean Validate(Object eo) {
            Type eoType = eo.GetType();
            IDictionary<String, EONhbmCase> eonc = Parse(eoType);
            PropertyInfo[] plist = eoType.GetProperties();
            foreach (PropertyInfo pi in plist) {
                if (!eonc.ContainsKey(pi.Name)) continue;

                EONhbmCase _case = eonc[pi.Name];
                Object val = pi.GetValue(eo, null);
                
                if (_case.NotNull) {
                    if(pi.PropertyType.Equals(typeof(String))){//字符串
                        if(val.ToString().Trim().Length<1){
                            Message = pi.Name + "不允许为空";
                            return false;
                        }
                    }else{//对象
                        if(val==null){
                            Message = pi.Name + "不允许为空";
                            return false;
                        }
                    }
                }
                if (_case.Length > 0 && _case.Type.Equals(typeof(String)) && val.ToString().Trim().Length > _case.Length) {
                    Message = pi.Name + "只能输入长度小于" + _case.Length + "的内容";
                    return false;
                }
            }
            return true;
        }
    }

}
